package com.terry.activity.controller;

import com.alibaba.fastjson.JSONObject;
import com.terry.activity.bean.ActivityModel;
import com.terry.activity.bean.EntryModel;
import com.terry.activity.bean.constant.ErrorCode;
import com.terry.activity.bean.exception.DataAlreadyExistException;
import com.terry.activity.bean.exception.DataNotExistException;
import com.terry.activity.bean.exception.WechatAuthException;
import com.terry.activity.bean.message.ResponseMsg;
import com.terry.activity.controller.base.BaseController;
import com.terry.activity.service.IActivityService;
import com.terry.activity.service.IEntryService;
import com.terry.activity.service.IVoteService;
import com.terry.activity.util.CommonUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Create On 18/4/25.
 *
 * @author TerrySolar
 */
@Controller
@RequestMapping(value = "/vote")
@CrossOrigin
public class VoteController extends BaseController {


    @Resource
    private IVoteService voteService;

    @Resource
    private IEntryService entryService;

    @Resource
    private IActivityService activityService;

    @Resource
    private JedisPool jedisPool;



    @ResponseBody
    @RequestMapping(value = "/submit", method = RequestMethod.POST)
    public ResponseMsg vote(Long entryId, HttpServletRequest request) throws WechatAuthException {

        assertWechatAuth(request);

        try {
            this.voteService.vote(entryId, OPEN_ID);
            return responseOK();
        } catch (DataAlreadyExistException e) {
            return responseError(ErrorCode.VOTE_ALREADY_EXIST, e.getMessage());
        } catch (DataNotExistException e) {
            return responseError(ErrorCode.ENTRY_NOT_EXIST, e.getMessage());
        }
    }


    @ResponseBody
    @RequestMapping(value = "/count", method = RequestMethod.GET)
    public ResponseMsg voteCount(Long activityId, HttpServletRequest request) throws WechatAuthException {

        assertWechatAuth(request);

        Map<Long, Integer> voteCount = new HashMap<>();

        List<EntryModel> entrys = this.entryService.retrieveAllEntryOfActivity(activityId);

        long entryNo = 0;
        for (EntryModel entry: entrys) {
            entryNo++;
            Integer entryCount = this.voteService.retrieveVoteCount(entry.getId());
            voteCount.put(entryNo, entryCount);
        }

        return responseData(voteCount);

    }


    @ResponseBody
    @RequestMapping(value = "/check", method = RequestMethod.GET)
    public ResponseMsg voteCheck(Long activityId, Long catalogId, HttpServletRequest request) throws WechatAuthException, DataNotExistException {

        assertWechatAuth(request);
        
        // 检查投票时间
        ActivityModel activityModel = this.activityService.getActivity(activityId);
        if (System.currentTimeMillis() < activityModel.getVoteStartTime()) {
            return responseError(ErrorCode.VOTE_TIME_ERROR, "投票暂未开放");
        } else if (System.currentTimeMillis() > activityModel.getVoteEndTime()) {
            return responseError(ErrorCode.VOTE_TIME_ERROR, "投票已经结束");
        }

        boolean isVoted = false;

        Jedis jedis = jedisPool.getResource();
        String redisKey;

        if (catalogId != null) {
            redisKey = CommonUtil.GenerateRedisKey("vote:" + OPEN_ID + ":" + activityId + ":" + catalogId);
        } else {
            redisKey = CommonUtil.GenerateRedisKey("vote:" + OPEN_ID + ":" + activityId);
        }

        // 先读缓存，否则读库
        if (jedis.get(redisKey) != null) {
            isVoted = true;
        } else {
            if (catalogId != null) {
                if (this.voteService.retrieveVote(OPEN_ID, activityId, catalogId) != null) {
                    isVoted = true;
                }
            } else {
                if (this.voteService.retrieveVote(OPEN_ID, activityId) != null) {
                    isVoted = true;
                }
            }

        }

        jedis.close();

        if (!isVoted) {
            return responseOK();
        } else {
            Map<Long, Integer> voteCount = new HashMap<>();
            Integer totalCount = 0;

            List<EntryModel> entrys;

            if (catalogId != null) {
                entrys = this.entryService.retrieveEntryOfActivityAndCatalog(activityId, catalogId);
            } else {
                entrys = this.entryService.retrieveAllEntryOfActivity(activityId);
            }

            long entryNo = 0;
            for (EntryModel entry: entrys) {
                entryNo++;
                Integer entryCount = this.voteService.retrieveVoteCount(entry.getId());
                voteCount.put(entryNo, entryCount);
                totalCount += entryCount;
            }

            JSONObject data = new JSONObject();
            data.put("voteCount", voteCount);
            data.put("totalCount", totalCount);

            return responseJson(data);
        }

    }








}
